home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / CPTUTT22.ZIP / CHAP08.TXT < prev    next >
Text File  |  1992-01-20  |  17KB  |  413 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.                                                         Chapter 8
  8.                                                  MORE INHERITANCE
  9.  
  10. In the last chapter we developed a model using modes of
  11. transportation to illustrate the concept of inheritance.  In this
  12. chapter we will use that model to illustrate some of the finer
  13. points of inheritance and what it can be used for.  If it has been
  14. a while since you read and studied chapter 7, it would be good for
  15. you to return to that material and review it in preparation for a
  16. more detailed study of the topic of inheritance.
  17.  
  18.  
  19.  
  20. REORGANIZED FILE STRUCTURE
  21. _________________________________________________________________
  22.  
  23. A close examination of the file named            ================
  24. INHERIT1.CPP will reveal that it is identical to   INHERIT1.CPP
  25. the program developed in chapter 7 named         ================
  26. ALLVEHIC.CPP except that the program text is
  27. rearranged.  The biggest difference is that some
  28. of the simpler methods in the classes have been changed to inline
  29. code to shorten the file considerably.  In a practical programming
  30. situation, methods that are this short should be programmed inline
  31. since the actual code to return a simple value is shorter than the
  32. code required to send a message to a non-inline method.
  33.  
  34. The only other change is the reordering of the classes and
  35. associated methods with the classes all defined first, followed by
  36. the main program.  This puts all class interface definitions on a
  37. single page to make the code easier to study.  The implementations
  38. for the methods are deferred until the end of the file where they
  39. are available for quick reference but are not cluttering up the
  40. class definitions which we wish to study carefully in this chapter.
  41. This should be an indication to you that there is considerable
  42. flexibility in the way the classes and methods can be arranged in
  43. C++.  Of course you realize that this violates the spirit of C++
  44. and its use of separate compilation, but is only done here for
  45. convenience.  The best way to package all of the example programs
  46. in this chapter is like the packaging illustrated in chapter 7.
  47.  
  48. As mentioned before, the two derived classes, car and truck, each
  49. have a variable named passenger_load which is perfectly legal, and
  50. the car class has a method of the same name, initialize(), as one
  51. defined in the super-class named vehicle.  The rearrangement of the
  52. files in no way voids this allowable repeating of names.
  53.  
  54. After you have convinced yourself that this program is truly
  55. identical to the program named ALLVEHIC.CPP from chapter 7, compile
  56. and execute it with your compiler to assure yourself that this
  57.  
  58.                                                          Page 8-1
  59.  
  60.                                      Chapter 8 - More Inheritance
  61.  
  62. arrangement is legal.  Due to this means of code packaging, you
  63. will not need a "make" file or a "project" capability to compile
  64. and execute this code.  This is to make it easy to compile and
  65. execute the example programs in this chapter.
  66.  
  67.  
  68. THE SCOPE OPERATOR
  69. _________________________________________________________________
  70.  
  71. Because the method initialize() is defined in the derived car
  72. class, it hides the method of the same name which is part of the
  73. base class, and there may be times you wish to send a message to
  74. the method in the base class for use in the derived class object.
  75. This can be done by using the scope operator in the following
  76. manner in the main program;
  77.  
  78.    sedan.vehicle::initialize(4, 3500.0);
  79.  
  80. As you might guess, the number and types of parameters must agree
  81. with those of the method in the base class because it will respond
  82. to the message.
  83.  
  84.  
  85.  
  86. HIDDEN METHODS
  87. _________________________________________________________________
  88.  
  89. Examine the file named INHERIT2.CPP carefully    ================
  90. and you will notice that it is a repeat of the     INHERIT2.CPP
  91. last example program with a few minor changes.   ================
  92.  
  93. You will notice that the derived classes named
  94. car and truck do not have the keyword public prior to the name of
  95. the base class in the first line of each.  The keyword public, when
  96. included prior to the base class name, makes all of the methods
  97. defined in the base class available for use in the derived class
  98. just as if they were defined as part of the derived class.
  99. Therefore, in the previous program, we were permitted to call the
  100. methods defined as part of the base class from the main program
  101. even though we were working with an object of one of the derived
  102. classes.  One example of when we did this, was when we sent a
  103. message to the sedan to get its weight in an output statement of
  104. the main program.
  105.  
  106. In the present program, without the keyword public prior to the
  107. base class name, the only methods available for objects of the car
  108. class, are those that are defined as part of the class itself, and
  109. therefore we only have the methods named initialize() and
  110. passengers() available for use with objects of class car.  In this
  111. program, the only inheritance is that of variables since the two
  112. variables are inherited into objects of class car.
  113.  
  114. When we declare an object of type car, according to the definition
  115. of the C++ language, it contains three variables.  It contains the
  116.  
  117.                                                          Page 8-2
  118.  
  119.                                      Chapter 8 - More Inheritance
  120.  
  121. one defined as part of its class named passenger_load and the two
  122. that are part of its parent class, wheels and weight.  All are
  123. available for direct use within its methods because of the use of
  124. the keyword protected in the base class.  The variables are a part
  125. of an object of class car when it is declared and are stored as
  126. part of the object.  We will show you the details of access to the
  127. parent class variables within derived classes shortly in this
  128. chapter.  For now, we will return to the use of the subclasses in
  129. this example program.
  130.  
  131. The observant student will notice that several of the output
  132. statements have been commented out of the main program since they
  133. are no longer legal or meaningful operations.  Lines 57 through 59
  134. have been commented out because the methods named get_weight() and
  135. wheel_loading() are not inherited into the car class without the
  136. keyword public in the car class definition.  You will notice that
  137. initialize() is still available but this is the one in the car
  138. class, not the method of the same name in the vehicle class.
  139.  
  140. Moving on to the use of the truck class in the main program, we
  141. find that lines 63 and 65 are commented out for the same reason as
  142. given above, but lines 66 and 67 are commented out for an entirely
  143. different reason.  Even though the method named efficiency() is
  144. available and can be called as a part of the truck class, it cannot
  145. be used because we have no way to initialize the wheels or weight
  146. of the truck objects.  We can get the weight of the truck objects,
  147. as we have done in line 106, but since the weight has no way to be
  148. initialized, the result is meaningless and lines 66 and 67 are
  149. commented out.
  150.  
  151. As you have surely guessed by now, there is a way around all of
  152. these problems and we will cover them shortly.  In the meantime,
  153. be sure to compile and execute this example program to see that
  154. your compiler gives the same result.  It would be a good exercise
  155. for you to reintroduce some of the commented out lines to see what
  156. sort of an error message your compiler issues for these errors.
  157.  
  158.  
  159. INITIALIZING ALL DATA
  160. _________________________________________________________________
  161.  
  162. If you will examine the example program named    ================
  163. INHERIT3.CPP, you will find that we have fixed     INHERIT3.CPP
  164. the initialization problem that we left dangling ================
  165. in the last example program.
  166.  
  167. The method named init_truck() now contains all four of the
  168. parameters as input data which get transferred to the four
  169. variables.  Following the initialization, it is permissible to call
  170. the semi.efficiency() method in line 67 and 68 of the main program.
  171.  
  172. Be sure to compile and execute this program following your detailed
  173. study of it.
  174.  
  175.  
  176.                                                          Page 8-3
  177.  
  178.                                      Chapter 8 - More Inheritance
  179.  
  180. WHAT IS PROTECTED DATA?
  181. _________________________________________________________________
  182.  
  183. Examine the program named INHERIT4.CPP for an    ================
  184. example we will use to define protected data.      INHERIT4.CPP
  185. Just to make the program more versatile, we have ================
  186. returned to the use of the keyword public prior
  187. to the name of the parent classes in lines 18
  188. and 29 of the class definitions.
  189.  
  190. If the data within a base class were totally available in all
  191. classes inheriting that base class, it would be a simple matter for
  192. a programmer to inherit the superclass into a derived class and
  193. have free access to all data in the parent class.  This would
  194. completely override the protection afforded by the use of
  195. information hiding.  For this reason, the data in a class are not
  196. automatically available to the methods of an inheriting class.
  197. There are times when you may wish to automatically inherit all
  198. variables directly into the subclasses and have them act just as
  199. though they were defined as a part of those classes also.  For this
  200. reason, the designer of C++ has provided the keyword protected.
  201.  
  202. In the present example program, the keyword protected is given in
  203. line 5 so that all of the data of the vehicle class can be directly
  204. imported into any derived classes but are not available outside of
  205. the class or derived classes.  All data are automatically defaulted
  206. to private type if no specifier is given.  The keyword private can
  207. be used as illustrated in lines 19 and 30 but adds nothing due to
  208. the fact that class members default to private by definition.
  209.  
  210. You will notice that the variables named wheels and weight are
  211. available to use in the method named initialize() in lines 85
  212. through 91 just as if they were declared as a part of the car class
  213. itself.  We can now state the rules for the three means of defining
  214. variables and methods.
  215.  
  216.      private - The variables and methods are not available to any
  217.           outside calling routines, and they are not available to
  218.           any derived classes inheriting this class.
  219.  
  220.      protected - The variables and methods are not available to any
  221.           outside calling routines, but they are directly available
  222.           to any derived class inheriting this class.
  223.  
  224.      public - All variables and methods are freely available to all
  225.           outside calling routines and to all derived classes.
  226.  
  227. You will note that these three means of definition can also be used
  228. in a struct type.  The only difference with a struct is that
  229. everything defaults to public until one of the other keywords is
  230. used.
  231.  
  232. Be sure to compile and execute this program before continuing on
  233. to the next example program.
  234.  
  235.                                                          Page 8-4
  236.  
  237.                                      Chapter 8 - More Inheritance
  238.  
  239. WHAT IS PRIVATE DATA?
  240. _________________________________________________________________
  241.  
  242. Examine the file named INHERIT5.CPP where the    ================
  243. data is allowed to use the private default.  In    INHERIT5.CPP
  244. this program, the data is not available for use  ================
  245. in the derived classes, so the only way the data
  246. in the base class can be used is through use of
  247. messages to methods in the base class.
  248.  
  249. It seems a little silly to have to call methods in the base class
  250. to get to the data which is actually a part of the derived class,
  251. but that is the way C++ is defined to work.  This would indicate
  252. to you that you should spend some time thinking about how any class
  253. you define will be used.  If you think somebody may wish to inherit
  254. your class into a new class and expand it, you should make the data
  255. members protected so they can be easily used in the new class.  Be
  256. sure to compile and execute this program.
  257.  
  258.  
  259.  
  260. INHERITING CONSTRUCTORS
  261. _________________________________________________________________
  262.  
  263. Examine the example program named INHERIT6.CPP   ================
  264. for yet another variation to our basic program,    INHERIT6.CPP
  265. this time adding constructors.                   ================
  266.  
  267. The vehicle class has a constructor to
  268. initialize the number of wheels and the weight to the indicated
  269. values and has no surprising constructs.  The car and truck classes
  270. each have a constructor also to initialize their unique variables
  271. to some unique values.  If you jump ahead to the main program, you
  272. will find that the initializing statements are commented out for
  273. each of the objects so we must depend on the constructors to
  274. initialize the variables.  The most important thing to glean from
  275. this example program is the fact that when one of the constructors
  276. is called for a derived class, the constructor is also called for
  277. the parent class.  In fact, the constructor for the parent class
  278. will be called before the constructor for the derived class is
  279. called.  All of the data will be initialized, including the data
  280. inherited from the parent class.
  281.  
  282. We will say much more about constructors used with inheritance in
  283. the next chapter of this tutorial.  Be sure to compile and execute
  284. this example program.
  285.  
  286.  
  287. POINTERS TO AN OBJECT AND AN ARRAY OF OBJECTS
  288. _________________________________________________________________
  289.  
  290. Examine the example program named INHERIT7.CPP for examples of the
  291. use of an array of objects and a pointer to an object.  In this
  292.  
  293.  
  294.                                                          Page 8-5
  295.  
  296.                                      Chapter 8 - More Inheritance
  297.  
  298. program, the objects are instantiated from an    ================
  299. inherited class and the intent of this program     INHERIT7.CPP
  300. is to illustrate that there is nothing magic     ================
  301. about a derived class.
  302.  
  303. The program is identical to the first program in this chapter until
  304. we get to the main program where we find an array of 3 objects of
  305. class car declared in line 52.  It should be obvious that any
  306. operation that is legal for a simple object is legal for an object
  307. that is part of an array, but we must be sure to tell the system
  308. which object of the array we are interested in by adding the array
  309. subscript as we do in lines 56 through 62.  The operation of this
  310. portion of the program should be very easy for you to follow, so
  311. we will go on to the next construct of interest.
  312.  
  313. You will notice, in line 65, that we do not declare an object of
  314. type truck but a pointer to an object of type truck.  In order to
  315. use the pointer, we must give it something to point at which we do
  316. in line 67 by dynamically allocating an object.  Once the pointer
  317. has an object to point to, we can use the object in the same way
  318. we would use any object, but we must use the pointer notation to
  319. access any of the methods of the object.  This is illustrated for
  320. you in lines 68 through 72, and will be further illustrated in the
  321. example program of chapter 12 in this tutorial.
  322.  
  323. Finally, we deallocate the object in line 73.  You should spend
  324. enough time with this program to thoroughly understand the new
  325. material presented here, then compile and execute it.
  326.  
  327.  
  328. THE NEW TIME CLASS
  329. _________________________________________________________________
  330.  
  331. We began a series of nontrivial classes in chapter 5 where we
  332. developed a date class, then a time class, and finally a newdate
  333. class in the last chapter.  Now it is your turn to add to this
  334. series.  Your assignment is to develop the newtime class which
  335. inherits the time class and adds a new member variable named
  336. seconds_today and a method to calculate the value of seconds since
  337. midnight to fill the variable.
  338.  
  339. A complete solution to this problem will be found in the ANSWERS
  340. directory on the distribution disk.  The files named NEWTIME.H,
  341. NEWTIME.CPP, and TRYNTIME.CPP are the solution files.  It would be
  342. a good exercise for you to attempt to write this new class before
  343. you look at the example solution.
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.                                                          Page 8-6
  354.  
  355.                                      Chapter 8 - More Inheritance
  356.  
  357. PROGRAMMING EXERCISES
  358. _________________________________________________________________
  359.  
  360. 1.   Remove the comment delimiters from lines 65 through 67 of
  361.      INHERIT2.CPP to see what kind of results are returned.  Remove
  362.      them from line 57 to see what kind of an error is reported by
  363.      the compiler for this error.
  364.  
  365. 2.   Add cout statements to each of the constructors of
  366.      INHERIT5.CPP to output messages to the monitor so you can see
  367.      the order of sending messages to the constructors.
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.                                                          Page 8-7
  413.